package com.ruoyi.platform.system.user.service;

import com.github.pagehelper.PageHelper;
import com.ruoyi.base.page.PageData;
import com.ruoyi.base.permission.TokenManager;
import com.ruoyi.base.redis.role.UserMenuRedis;
import com.ruoyi.base.service.BaseService;
import com.ruoyi.platform.system.menu.pojo.MenuTreeDTO;
import com.ruoyi.platform.system.user.dao.UserDAO;
import com.ruoyi.platform.system.user.dao.role.UserRoleDAO;
import com.ruoyi.platform.system.user.manager.UserManager;
import com.ruoyi.platform.system.user.manager.role.UserRoleManager;
import com.ruoyi.platform.system.user.pojo.UserDO;
import com.ruoyi.platform.system.user.pojo.UserDTO;
import com.ruoyi.platform.system.user.pojo.UserEditQuery;
import com.ruoyi.platform.system.user.pojo.UserListDTO;
import com.ruoyi.platform.system.user.pojo.role.UserRoleDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户信息表
 *
 * @author lcf
 * @version 0.0.1
 * @since 2020-11-13 05:40:22
 */
@Slf4j
@Service
@Scope("prototype")
public class UserService extends BaseService {
    @Autowired
    private UserDAO sysUserDao;
    @Autowired
    private TokenManager tokenService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private UserRoleManager userRoleManager;
    @Autowired
    private UserMenuRedis userMenuRedis;
    @Autowired
    private UserRoleDAO userRoleDAO;

    /**
     * 获取用户列表
     */
    public PageData<UserDO, UserListDTO> getUserPlatList(int pageNum, int pageSize, String nickName) {
        PageHelper.startPage(pageNum, pageSize);
        List<UserDO> userList = sysUserDao.selectPlatList(nickName);

        if (CollectionUtils.isEmpty(userList)) {
            return new PageData<>(userList, UserListDTO::new);
        }

        List<Long> userIdList = userList.stream().map(UserDO::getUserId).collect(Collectors.toList());
        List<UserRoleDTO> roleList = userRoleManager.getUserRoleList(userIdList);
        return new PageData<>(userList, x -> new UserListDTO(x, roleList));
    }

    /**
     * 获取用户详情
     */
    public UserDTO getUserDetail(long userId) {
        UserDO user = userManager.checkUserId(userId);
        List<UserRoleDTO> roleList = userRoleManager.getUserRoleList(Collections.singletonList(userId));
        return new UserDTO(user, roleList);
    }

    /**
     * 获取用户菜单权限列表
     */
    public List<MenuTreeDTO> getRoleMenuTree(long userId) {
        return userMenuRedis.getList(userId);
    }

    /**
     * 修改用户
     */
    @Transactional(rollbackFor = Exception.class)
    public void editUser(long userId, UserEditQuery query, List<Long> roleCodeList) {
        userManager.checkSystemUser(userId);
        userManager.checkUserId(userId);
        //检查手机号是否存在
        userManager.checkPhoneExist(userId, query.getPhone());

        sysUserDao.updateUserByPrimaryKeySelective(query.convert(userId));
        userRoleManager.editUserRole(userId, roleCodeList);

        userMenuRedis.delCache(userId);
        //刷新登陆缓存
        tokenService.refreshCache(tokenService.getLoginUserId());
    }

    /**
     * 修改我的信息
     */
    public void editUser(UserEditQuery query) {
        long userId = tokenService.getLoginUserId();
        //检查手机号是否存在
        userManager.checkPhoneExist(userId, query.getPhone());

        sysUserDao.updateUserByPrimaryKeySelective(query.convert(userId));

        //刷新登陆缓存
        tokenService.refreshCache(userId);
    }

    /**
     * 修改账号状态
     */
    public void editAccountStatus(long userId, int accountStatus) {
        userManager.checkSystemUser(userId);
        userManager.checkUserId(userId);

        sysUserDao.updateUserByPrimaryKeySelective(new UserDO(userId, accountStatus));

        //刷新登陆缓存
        tokenService.refreshCache(userId);
    }

    /**
     * 删除用户
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(long userId) {
        userManager.checkSystemUser(userId);

        sysUserDao.delUserByPrimaryKey(userId);
        userRoleDAO.delByUserId(userId);

        userMenuRedis.delCache(userId);
        //刷新登陆缓存
        tokenService.refreshCache(userId);
    }
}